/*
 * ATGM336H-5N BDS/GNSS全星座定位导航模块
 */
#include "head\ATGM336.h"
#include "head\MCU.h"

void ATGM336H_Init()
{
    /*
     * 配置电源控制引脚
     */
    GPIO_setAsOutputPin(ATGM336H_LED_PORT,ATGM336H_LED_PIN);
    ATGM336H_ledOFF();

    /*
     * 配置串口引脚
     */
    GPIO_setAsPeripheralModuleFunctionInputPin(ATGM336H_USCI_PORT,
                                               ATGM336H_USCI_PIN_TX + ATGM336H_USCI_PIN_RX);

    /*
     * 配置串口
     */
    USCI_A_UART_initParam param = {0};
    param.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK; //选择SMCLK为时钟源
    if(MSP430_FREQUENCY == 25165824)
    {
        param.clockPrescalar = 2621;//25,165,824
        param.secondModReg = 4;
    }
    else if(MSP430_FREQUENCY == 16777216)
    {
        param.clockPrescalar = 1747;//16,777,216
        param.secondModReg = 5;
    }
//    param.clockPrescalar = 873;//8,388,608
//    param.secondModReg = 7;//
//    param.clockPrescalar = 109; //109.22666 ~= 1048676/9600
//    param.secondModReg = 2; //0.22666*8 ~= 1.81333 ~= 2
    param.firstModReg = 0; //这个是用在过采样波特率模式，公式见用户手册36.3.10.2
    param.parity = USCI_A_UART_NO_PARITY; //奇偶校验
    param.msborLsbFirst = USCI_A_UART_LSB_FIRST; //“控制移位寄存器的方向”，及大小端。LSB属于小端，高位字节放高端
    param.numberofStopBits = USCI_A_UART_ONE_STOP_BIT; //停止位数
    param.uartMode = USCI_A_UART_MODE; //普通串口模式
    param.overSampling = USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION; //低采样波特率或过采样波特率选择
    if (STATUS_FAIL == USCI_A_UART_init(ATGM336H_USCI_BASE, &param)){
        return;
    }

    /*
     * 使能串口模块操作
     */
    USCI_A_UART_enable(ATGM336H_USCI_BASE);//UCSWRST位置1

//    __delay_cycles(MSP430_FREQUENCY);
//    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,1,0,0,1");//设置为仅发出RMC与TXT信息
//    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,0,0,0,1");//设置为仅发出TXT信息
    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,0,0,0,0");//停止发出所有信息

    /*
     * 使能串口接收中断
     */
    USCI_A_UART_clearInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);//标志位清除
    USCI_A_UART_disableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);//使能位置位
}

void ATGM336H_getRMC(uint8_t *RxBuff,uint16_t *RxCount)
{
    uint8_t Timeing;
    uint8_t lastCount = 0;
    pATGM336hRxData = RxBuff;
    pATGM336hRxCount = RxCount;
    //清空缓存
    memset(pATGM336hRxData, 0, ATGM336H_GPS_Buffer_Length);
    *pATGM336hRxCount = 0;
    //使能中断
    USCI_A_UART_clearInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);//标志位清除
    USCI_A_UART_enableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);//使能位置位
    //让模块开始发送数据
    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,1,0,0,0");
    //等待数据发出
    Timeing = 11;//等待11个0.1秒
    while(*pATGM336hRxCount==0){
        __delay_cycles(MSP430_FREQUENCY/10);
        Timeing--;
        if(Timeing == 0)
        {
            __no_operation();
            //禁用中断
            USCI_A_UART_disableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
            //让模块停止发送数据
            ATGM336H_sendControlMessage("PCAS03,0,0,0,0,0,0,0,0");
            break;
        }
    }
    //等待数据发完
    while(lastCount != *pATGM336hRxCount)
    {
        lastCount = *pATGM336hRxCount;
        __delay_cycles(MSP430_FREQUENCY/100);
    }
    //禁用中断
    USCI_A_UART_disableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
    //让模块停止发送数据
    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,0,0,0,0");
}

void ATGM336H_getRMCandTXT(uint8_t *RxBuff,uint16_t *RxCount)
{
    uint8_t Timeing;
    uint8_t lastCount = 0;
    pATGM336hRxData = RxBuff;
    pATGM336hRxCount = RxCount;
    //清空缓存
    memset(pATGM336hRxData, 0, ATGM336H_GPS_Buffer_Length);
    *pATGM336hRxCount = 0;
    //使能中断
    USCI_A_UART_clearInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);//标志位清除
    USCI_A_UART_enableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);//使能位置位
    //让模块开始发送数据
    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,1,0,0,1");
    //等待数据发出
    Timeing = 11;//等待11个0.1秒
    while(*pATGM336hRxCount==0){
        __delay_cycles(MSP430_FREQUENCY/10);
        Timeing--;
        if(Timeing == 0)
        {
            __no_operation();
            //禁用中断
            USCI_A_UART_disableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
            //让模块停止发送数据
            ATGM336H_sendControlMessage("PCAS03,0,0,0,0,0,0,0,0");
            return;
        }
    }
    //等待数据发完
    while(lastCount != *pATGM336hRxCount)
    {
        lastCount = *pATGM336hRxCount;
        __delay_cycles(MSP430_FREQUENCY/100);
    }
    //禁用中断
    USCI_A_UART_disableInterrupt(ATGM336H_USCI_BASE,USCI_A_UART_RECEIVE_INTERRUPT);
    //让模块停止发送数据
    ATGM336H_sendControlMessage("PCAS03,0,0,0,0,0,0,0,0");
}

uint8_t ATGM336H_checkStatus(uint8_t *RxBuff,uint16_t *RxCount)
{
    ATGM336H_getRMCandTXT(RxBuff,RxCount);
    if (strstr(RxBuff, ",A*"))//寻找定位模式标志位，表示正常的A
    {
        return 0;//如果找到相当于正常工作
    }
    else if(strstr(RxBuff, "OPEN"))
    {
        return 2;//天线开路
    }
    else if(strstr(RxBuff, "OK"))
    {
        return 1;//天线状态工作正常
    }
    else if(strstr(RxBuff, "SHORT"))
    {
        return 3;//天线短路
    }
    return 4;
}

void ATGM336H_sendControlMessage(uint8_t *message)
{
    uint8_t cs = 0;//用于计算异或校验和
    uint8_t csHight;
    uint8_t csLow;
    uint8_t *p;

    //计算cs
    for(p = message; *p != '\0'; p++){
        cs ^= *p;
    }
    //将cs转换成两个16进制字符
    csHight = (cs&0xf0)>>4;
    if(csHight > 0x09){
        csHight += 0x37;
    }
    else{
        csHight += 0x30;
    }
    csLow = cs&0x0f;
    if(csLow > 0x09){
        csLow += 0x37;
    }
    else{
        csLow += 0x30;
    }

    //发送message头部
    USCI_A_UART_transmitData(ATGM336H_USCI_BASE,'$');
    //发送数据主体
    for(p = message; *p != '\0'; p++)
    {
        USCI_A_UART_transmitData(ATGM336H_USCI_BASE,*p);
    }
    //发送校验和cs
    USCI_A_UART_transmitData(ATGM336H_USCI_BASE,'*');
    USCI_A_UART_transmitData(ATGM336H_USCI_BASE,csHight);
    USCI_A_UART_transmitData(ATGM336H_USCI_BASE,csLow);
    //发送回车换行<CR><LF>
    USCI_A_UART_transmitData(ATGM336H_USCI_BASE,'\r');
    USCI_A_UART_transmitData(ATGM336H_USCI_BASE,'\n');
    __no_operation();
}

void ATGM336H_ledON()
{
    GPIO_setOutputLowOnPin(ATGM336H_LED_PORT,ATGM336H_LED_PIN);
}

void ATGM336H_ledOFF()
{
    GPIO_setOutputHighOnPin(ATGM336H_LED_PORT,ATGM336H_LED_PIN);
}

void ATGM336H_ledToggle()
{
//    GPIO_toggleOutputOnPin(ATGM336H_LED_PORT,ATGM336H_LED_PIN);
    ATGM336H_LED_REG_PORT ^= ATGM336H_LED_REG_PIN;
}
//******************************************************************************
//
//This is the USCI_A2 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A2_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_A2_VECTOR)))
#endif
void ATGM336H_USCI_A2_ISR (void)
{
    switch (__even_in_range(UCA2IV,4)){
        case 2://Vector 2 - RXIFG
        {
            *pATGM336hRxData++ = USCI_A_UART_receiveData(ATGM336H_USCI_BASE);
            (*pATGM336hRxCount)++;
            break;
        }
        default: break;
    }
}

